package org.tloss.web.editor.form.editors.command;

import java.util.Collections;
import java.util.List;

import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.DialogCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.tloss.web.editor.model.Form;
import org.tloss.web.editor.model.command.If;
import org.tloss.web.editor.model.oper.logical.CompareLogical;
import org.tloss.web.editor.model.oper.logical.CompareOperator;
import org.tloss.web.editor.model.oper.logical.IsEmptyOperator;
import org.tloss.web.editor.model.oper.math.MathOperand;
import org.tloss.web.editor.utils.LogicalBuilder;
import org.tloss.web.editor.utils.Variable;
import org.tloss.web.editor.utils.VariableBrowser;
import org.tloss.web.editor.utils.VariableProvider;

public class IfProperty implements IPropertySource {
	public static final String CONDITION_PRO = "CONDITION_PRO";
	private If command;
	private IResourceChangeListener listener;
	private Form form;

	private IPropertyDescriptor[] descriptors;

	public Form getForm() {
		return form;
	}

	public IfProperty() {
		descriptors = new IPropertyDescriptor[1];
		descriptors[0] = new PropertyDescriptor(CONDITION_PRO, "Condition") {
			public CellEditor createPropertyEditor(Composite parent) {
				DialogCellEditor cellEditor = new DialogCellEditor(parent) {
					@Override
					protected Object openDialogBox(Control arg0) {
						Dialog dialog = IfProperty.this.new BuilderDialog(
								arg0.getShell());
						dialog.open();
						return command;
					}
				};
				return cellEditor;
			};
		};
	}

	public If getCommand() {
		return command;
	}

	public void setForm(Form form) {
		this.form = form;
	}

	public void setCommand(If command) {
		this.command = command;
	}

	public IResourceChangeListener getListener() {
		return listener;
	}

	public void setListener(IResourceChangeListener listener) {
		this.listener = listener;
	}

	@Override
	public Object getEditableValue() {
		return this;
	}

	@Override
	public IPropertyDescriptor[] getPropertyDescriptors() {
		return descriptors;
	}

	@Override
	public Object getPropertyValue(Object arg0) {
		if (CONDITION_PRO.equals(arg0)) {
			return command.getLabel() != null ? command.getLabel() : "";
		}
		return null;
	}

	@Override
	public boolean isPropertySet(Object arg0) {

		return false;
	}

	@Override
	public void resetPropertyValue(Object arg0) {

	}

	@Override
	public void setPropertyValue(Object arg0, Object arg1) {

	}

	class BuilderDialog extends Dialog {

		protected BuilderDialog(Shell parentShell) {
			super(parentShell);
			setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE);
		}

		protected Point getInitialSize() {
			Point size = getShell().computeSize(510, 540);
			return size;
		}

		@Override
		protected Control createDialogArea(Composite parent) {
			
			LogicalBuilder builder = new LogicalBuilder() {
				@Override
				public List<CompareOperator> getCompareOperators() {
					List<CompareOperator> compareOperators =  super.getCompareOperators();
					if(compareOperators !=null){
						compareOperators.add(new IsEmptyOperator());
					}
					return compareOperators;
				}
				@SuppressWarnings("unchecked")
				@Override
				public List<Object> getOperandList() {
					if (listener instanceof VariableProvider) {
						return ((VariableProvider) listener)
								.getCurrentCommandVariables();
					}
					return Collections.EMPTY_LIST;
				}

				@Override
				public EditingSupport getOperand1EditingSupport(
						TreeViewer columnViewer) {
					return new EditingSupport(columnViewer) {

						@Override
						protected boolean canEdit(Object arg0) {
							if (arg0 instanceof CompareLogical)
								return true;
							return false;
						}

						@Override
						protected CellEditor getCellEditor(Object arg0) {
							DialogCellEditor cellEditor = new DialogCellEditor(
									(Composite) treeViewer.getControl()) {

								@Override
								protected Object openDialogBox(Control arg0) {
									VariableBrowser dialog = new VariableBrowser(
											arg0.getShell());
									dialog.setSupportedVariable(getOperandList());
									if (dialog.open() == Window.OK) {
										List<Variable> variables = dialog
												.getVariable();
										if (variables.size() > 0)
											return variables.get(0);
									}
									return null;
								}
							};
							return cellEditor;
						}

						@Override
						protected Object getValue(Object arg0) {

							return (arg0 != null && (arg0 instanceof CompareLogical)) ? (((CompareLogical) arg0)
									.getOperand1() != null ? ((CompareLogical) arg0)
									.getOperand1() : "")
									: "";
						}

						@Override
						protected void setValue(Object arg0, Object arg1) {
							if (arg1 != null && arg1 instanceof Variable) {
								if (arg0 instanceof CompareLogical) {
									MathOperand operand = ((Variable) arg1)
											.convertToMathOperand();
									if (operand != null) {
										((CompareLogical) arg0)
												.setOperand1(operand);
										treeViewer.refresh();
										if (dirtyListener != null) {
											dirtyListener.resourceChanged(null);
										}
									}
								}
							}
						}
					};
				}

				@Override
				public EditingSupport getOperand2EditingSupport(
						TreeViewer columnViewer) {

					return new EditingSupport(columnViewer) {

						@Override
						protected boolean canEdit(Object arg0) {
							if (arg0 != null && arg0 instanceof CompareLogical) {
								CompareOperator operator = ((CompareLogical) arg0)
										.getOperator();
								if (operator != null
										&& !operator.supportTwoOperand()) {
									return false;
								}
								return true;
							}
							return false;
						}

						@Override
						protected CellEditor getCellEditor(Object arg0) {
							DialogCellEditor cellEditor = new DialogCellEditor(
									(Composite) treeViewer.getControl()) {

								@Override
								protected Object openDialogBox(Control arg0) {
									VariableBrowser dialog = new VariableBrowser(
											arg0.getShell());
									dialog.setSupportedVariable(getOperandList());
									if (dialog.open() == Window.OK) {
										List<Variable> variables = dialog
												.getVariable();
										if (variables.size() > 0)
											return variables.get(0);
									}
									return null;
								}
							};
							return cellEditor;
						}

						@Override
						protected Object getValue(Object arg0) {

							return (arg0 != null && (arg0 instanceof CompareLogical)) ? (((CompareLogical) arg0)
									.getOperand2() != null ? ((CompareLogical) arg0)
									.getOperand2() : "")
									: "";
						}

						@Override
						protected void setValue(Object arg0, Object arg1) {
							if (arg1 != null && arg1 instanceof Variable) {
								if (arg0 instanceof CompareLogical) {
									MathOperand operand = ((Variable) arg1)
											.convertToMathOperand();
									if (operand != null) {
										((CompareLogical) arg0)
												.setOperand2(operand);
										treeViewer.refresh();
										if (dirtyListener != null) {
											dirtyListener.resourceChanged(null);
										}
									}
								}
							}
						}
					};
				}

			};
			builder.setLogicalProvider(command);
			builder.setDirtyListener(listener);
			return builder.createPartControl(parent);
		}
	}
}
